﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
//new
using System.IO;
using JRCore.tools;
using JRCore.enums;
using DataRecv.models;
using DataRecv.models.road;
using DataRecv.models.device;
using DataRecv.models.recever;
using DataRecv.tools;
using System.Collections;
using DataRecv.enums;
using JRCore.protocol;
using DataRecv.models.mq;

namespace DataRecv
{
    public partial class Form_Main : Form
    {
        private LogTool m_log;
        private WatchDog m_dog;
        private delegate void SetTxt(string txt);
        private delegate void SetCamState(string camip, bool online);
        private SetTxt m_showlog;
        private SetCamState m_SetCamStateInvoke;
        private Timer m_DailyCloseTimer;
        private bool m_start = false;
        private StatusReporter m_rpt;

        public Form_Main()
        {
            InitializeComponent();
        }

        private void Form_Main_Load(object sender, EventArgs e)
        {
            try
            {
                m_log = new LogTool();//日志
                m_log.LogComingEvent += new LogTool.LogEvent(m_log_LogComingEvent);
                m_showlog = new SetTxt(ShowLogFunc);
                
                //G.SetAutoRun();//注册随系统启动
                G.SystemParam = new SystemParam();//系统参数
                G.BRTs = G.LoadBRTs();//BRT车辆
                G.Roads = Road.GetModels();//路口参数
                G.Views = DeviceView.GetModels();//静态设备参数视图
                G.Worker = new Worker();//图片处理
                G.DiskRecyles = new List<DiskRecyle>();//磁盘空间清理

                LogTool.gWorkEnable = G.SystemParam.WorkLogEnable;
                LogTool.gDebugEnable = G.SystemParam.DebugLogEnable;

                if (Road.KKDistinctPathList != null)
                {
                    foreach (string path in Road.KKDistinctPathList)//卡口磁盘空间清理
                    {
                        G.DiskRecyles.Add(new DiskRecyle(path, G.SystemParam.KKSaveDays, G.SystemParam.KKSubFolderMode));
                    }
                }
                if (Road.DJDistinctPathList != null)
                {
                    foreach (string path in Road.DJDistinctPathList)//电警磁盘空间清理
                    {
                        G.DiskRecyles.Add(new DiskRecyle(path, G.SystemParam.DJSaveDays, G.SystemParam.DJSubFolderMode));
                    }
                }

                if (G.SystemParam.DogEnable)//硬件看门狗
                {
                    m_dog = new WatchDog(G.SystemParam.DogPort, G.SystemParam.DogEnableShutDown, G.SystemParam.DogShutDownHour, G.SystemParam.DogShutDownMin, G.SystemParam.DogShutDownSpan);//看门狗
                    m_dog.ShutDownEvent += new WatchDog.ShutDown(m_dog_ShutDownEvent);
                }

                if (G.SystemParam.DailyCloseEnable)//软件每日定时退出
                {
                    m_DailyCloseTimer = new Timer();
                    m_DailyCloseTimer.Interval = 5000;
                    m_DailyCloseTimer.Tick += new EventHandler(m_SoftRestartTimer_Tick);
                    m_DailyCloseTimer.Start();
                }

                //路口树
                UpDateTree();

                //卡口实时上传
                if (G.SystemParam.KKUploadEnable)
                {
                    G.KKClient = new Client(G.SystemParam.KKUploadIP, int.Parse(G.SystemParam.KKUploadPort), Enum_TcpWorkMode.SendRead,0);
                    G.KKClient.OnRecordReceived = new Client.RecordReceived(OnKKRecordReceivedFunc);

                    //失败重传
                    if(G.SystemParam.KKFailReTryEnable)
                    {   
                        G.KKReUpload = new ReUpload(true);
                    }
                }

                //电警实时上传
                if (G.SystemParam.DJUploadEnable)
                {
                    G.DJClient = new Client(G.SystemParam.DJUploadIP, int.Parse(G.SystemParam.DJUploadPort), Enum_TcpWorkMode.SendRead,0);
                    G.DJClient.OnRecordReceived = new Client.RecordReceived(OnDJRecordReceivedFunc);

                    //失败重传
                    if(G.SystemParam.DJFailReTryEnable)
                    {   
                        G.DJReUpload = new ReUpload(false);
                    }
                }

                //第三方推送
                if ((G.SystemParam.KKPushEnable == true) || (G.SystemParam.DJPushEnable == true))
                {
                    G.PushServer = new Server(G.SystemParam.LocalIP, G.SystemParam.PushPort, G.SystemParam.PushWorkMode, int.Parse(G.SystemParam.PushTimeOut));
                    
                    //失败重推
                    if (G.SystemParam.KKRePushEnable==true)
                    {
                        G.KKRePush = new RePush(true);
                    }

                    //失败重推
                    if (G.SystemParam.DJRePushEnable == true)
                    {
                        G.DJRePush = new RePush(false);
                    }
                }


                //开SDK接收
                G.Recever_HK = new Recever_HK();
                G.Recever_DH = new Recever_DH();

                //设备状态推送
                m_SetCamStateInvoke = new SetCamState(SetCamStateFunc);
                Device.OnStateChangedEvent += new Device.StateChanged(Device_OnStateChangedEvent);

                //开Device设备
                G.Devices = new List<Device>();
                if (G.Views != null)
                {
                    
                    System.Threading.ThreadPool.SetMaxThreads(1000, 1000);
                    System.Threading.ThreadPool.SetMinThreads(500, 500);

                    IDictionaryEnumerator ide = G.Views.GetEnumerator();
                    ide.Reset();
                    while (ide.MoveNext())
                    {
                        DeviceView view = (DeviceView)ide.Value;

                        switch (view.deviceparam.type)
                        {
                            case Enum_DeviceType.DH:
                                DH device_dh = new DH(view);
                                device_dh.Run();
                                G.Devices.Add(device_dh);
                                break;
                            case Enum_DeviceType.HK5012:
                                HK5012 device_hk5012 = new HK5012(view);
                                device_hk5012.Run();
                                G.Devices.Add(device_hk5012);
                                break;
                            case Enum_DeviceType.HK9121:
                                HK9121 device_hk9121 = new HK9121(view);
                                device_hk9121.Run();
                                G.Devices.Add(device_hk9121);
                                break;
                            case Enum_DeviceType.HK9151:
                                HK9151 device_hk9151 = new HK9151(view);
                                device_hk9151.Run();
                                G.Devices.Add(device_hk9151);
                                break;
                            case Enum_DeviceType.HK9361:
                                HK9361 device_hk9361 = new HK9361(view);
                                device_hk9361.Run();
                                G.Devices.Add(device_hk9361);
                                break;
                            case Enum_DeviceType.HK9371:
                                HK9371 device_hk9371 = new HK9371(view);
                                device_hk9371.Run();
                                G.Devices.Add(device_hk9371);
                                break;
                            case Enum_DeviceType.HK986:
                                HK986 device_hk986 = new HK986(view);
                                device_hk986.Run();
                                G.Devices.Add(device_hk986);
                                break;
                            case Enum_DeviceType.HV:
                                break;
                            case Enum_DeviceType.MaxFord:
                                break;
                            default:
                                break;
                        }
                    }
                }

                //卡口电警统计
                G.KKCount = new List<KKTongJiParam>();
                G.DJCount = new List<DJTongJiParam>();
                if (G.Views != null)
                {
                    IDictionaryEnumerator ide = G.Views.GetEnumerator();
                    ide.Reset();
                    while (ide.MoveNext())
                    {
                        DeviceView view = (DeviceView)ide.Value;
                        KKTongJiParam kk = new KKTongJiParam(view.deviceparam.ip, view.roadparam.roadname, view.deviceparam.direction.ToString());
                        G.KKCount.Add(kk);

                        DJTongJiParam dj = new DJTongJiParam(view.deviceparam.ip, view.roadparam.roadname, view.deviceparam.direction.ToString());
                        G.DJCount.Add(dj);
                    }
                }
                
                this.checkBox_debug.Checked = G.SystemParam.DebugLogEnable;
                this.checkBox_work.Checked = G.SystemParam.WorkLogEnable;

                m_rpt = new StatusReporter();
            }
            catch { }
        }


        private bool OnKKRecordReceivedFunc(ref Msg send, Msg read, ref string error)
        {
            bool ans = false;
            try
            {
                // 收到消息的处理函数，解析服务器反馈的处理结果，或者处理对服务器返回信息
                // 重新委托此函数用以对反馈消息和请求信息进行验证和处理：
                // 1.反馈消息类型是否与请求消息类型匹配（反馈比请求大1）
                // 2.反馈uuid是否和请求uuid一致
                // 3.反馈信息的密钥是否正确(如果协议中需要)。
                // 4.服务器的处理结果
                // 5.进行自定义协议的处理，并反馈结果
                if ((send.type == Enum_ProtocolType.Upload) && (read.type == Enum_ProtocolType.UploadFeedback))
                {
                    if (send.uuid == read.uuid)
                    {
                        if ((send.data != null) && (read.data != null))
                        {
                            DataRecvRecord record = DataRecvRecord.Parse(send.data);
                            DataRecvFeedBack back = DataRecvFeedBack.Parse(read.data);
                            if ((record != null) && (back != null))
                            {
                                if (back.P2 == "1")
                                {
                                    ans = true;
                                }
                                else if (back.P2 == "0")
                                {
                                    error = back.P3;
                                    //屏蔽重复录入违反UK
                                    if (error.Contains("ORA-00001") ||
                                        error.Contains("ORA-00604") ||
                                        error.Contains("ORA-24381"))
                                    {
                                        ans = true;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        error = "uuid不一致";
                    }
                }
                else
                {
                    error = "消息类型错误";
                }
            }
            catch (Exception er)
            {
                ans = false;
                error = er.Message;
            }
            return ans;
        }

        private bool OnDJRecordReceivedFunc(ref Msg send, Msg read, ref string error)
        {
            bool ans = false;
            try
            {
                // 收到消息的处理函数，解析服务器反馈的处理结果，或者处理对服务器返回信息
                // 重新委托此函数用以对反馈消息和请求信息进行验证和处理：
                // 1.反馈消息类型是否与请求消息类型匹配（反馈比请求大1）
                // 2.反馈uuid是否和请求uuid一致
                // 3.反馈信息的密钥是否正确(如果协议中需要)。
                // 4.服务器的处理结果
                // 5.进行自定义协议的处理，并反馈结果
                if ((send.type == Enum_ProtocolType.Upload) && (read.type == Enum_ProtocolType.UploadFeedback))
                {
                    if (send.uuid == read.uuid)
                    {
                        if ((send.data != null) && (read.data != null))
                        {
                            DataRecvRecord record = DataRecvRecord.Parse(send.data);
                            DataRecvFeedBack back = DataRecvFeedBack.Parse(read.data);
                            if ((record != null) && (back != null))
                            {
                                if (back.P2 == "1")
                                {
                                    ans = true;
                                }
                                else if (back.P2 == "0")
                                {
                                    error = back.P3;
                                    //屏蔽重复录入违反UK
                                    if (error.Contains("ORA-00001") ||
                                        error.Contains("ORA-00604") ||
                                        error.Contains("ORA-24381"))
                                    {
                                        ans = true;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        error = "uuid不一致";
                    }
                }
                else
                {
                    error = "消息类型错误";
                }
            }
            catch (Exception er)
            {
                ans = false;
                error = er.Message;
            }
            return ans;
        }


        void Device_OnStateChangedEvent(string camip, bool online)
        {
            this.treeView1.Invoke(m_SetCamStateInvoke, new object[2] { camip, online });
        }

        /// <summary>
        /// 硬件看门狗关闭
        /// </summary>
        private void m_dog_ShutDownEvent()
        {
            try
            {
                this.Close();
                G.ShutDown();
            }
            catch { }
        }

        private void MyClose()
        {
            try
            {
                //关摄像机
                if (G.Devices != null)
                {
                    foreach (Device device in G.Devices)
                    {
                        device.ShutDown();
                    }
                    G.Devices.Clear();
                }
            }
            catch { }

            try
            {
                if (G.KKCount != null)
                {
                    foreach (KKTongJiParam p in G.KKCount)
                    {
                        p.Save();
                    }
                }
            }
            catch { }

            try
            {
                if (G.DJCount != null)
                {
                    foreach (DJTongJiParam p in G.DJCount)
                    {
                        p.Save();
                    }
                }
            }
            catch { }

            try
            {
                if (G.Recever_HK != null) G.Recever_HK.Close();
            }
            catch { }

            try
            {
                if (G.Recever_DH != null) G.Recever_DH.Close();
            }
            catch { }

            try
            {
                if (G.Roads != null)
                {
                    G.Roads.Clear();
                }
            }
            catch { }

            try
            {
                if (G.DiskRecyles != null)
                {
                    foreach (DiskRecyle dr in G.DiskRecyles)
                    {
                        dr.Dispose();
                    }
                    G.DiskRecyles.Clear();
                }
            }
            catch { }

            try
            {
                if ((G.SystemParam.DogEnable)&&(m_dog!=null))
                {
                    m_dog.ShutDownEvent -= m_dog_ShutDownEvent;
                    m_dog.Dispose();
                }
            }
            catch { }

            try
            {
                if ((G.SystemParam.DailyCloseEnable)&&(m_DailyCloseTimer!=null))
                {
                    m_DailyCloseTimer.Stop();
                    m_DailyCloseTimer.Dispose();
                }
            }
            catch { }

            try
            {
                if ((G.SystemParam.KKUploadEnable)&&(G.KKClient!=null))
                {
                    G.KKClient.Dispose();
                    G.KKClient = null;
                }
            }
            catch { }

            try
            {
                if (G.KKReUpload != null) G.KKReUpload.Dispose();
            }
            catch { }

            try
            {
                if ((G.SystemParam.DJUploadEnable) && (G.DJClient != null))
                {
                    G.DJClient.Dispose();
                    G.DJClient = null;
                }
            }
            catch { }

            try
            {
                if (G.DJReUpload != null) G.DJReUpload.Dispose();
            }
            catch { }

            try
            {
                if (G.PushServer != null) G.PushServer.Dispose();
            }
            catch { }

            try
            {
                if (G.KKRePush != null) G.KKRePush.Dispose();
            }
            catch { }

            try
            {
                if (G.DJRePush != null) G.DJRePush.Dispose();
            }
            catch { }

            try
            {
                if (m_rpt != null) m_rpt.Dispose();
            }
            catch { }

            try
            {
                if (m_log != null)
                {
                    m_log.LogComingEvent -= m_log_LogComingEvent;
                    m_log.Dispose();
                }
            }
            catch { }

            GC.Collect();
        }

        private void ToolStripMenuItem_exit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        #region 日志
        private void m_log_LogComingEvent(string msg)
        {
            try
            {
                this.dataGridView1.Invoke(m_showlog, msg);
            }
            catch { }
        }

        private void ShowLogFunc(string txt)
        {
            try
            {
                if (this.dataGridView1.Rows.Count > 15)
                {
                    this.dataGridView1.Rows.Clear();
                }
                else
                {
                    this.dataGridView1.Rows.Add(new object[] { DateTime.Now.ToLongTimeString(), txt });
                }
            }
            catch { }
        }
        #endregion

        void SetCamStateFunc(string camip, bool online)
        {
            try
            {
                TreeNode[] camnode = treeView1.Nodes.Find("device_" + camip, true);
                if ((camnode != null) && (camnode.Length == 1))
                {
                    camnode[0].ImageIndex = (online ? 1 : 2);
                    camnode[0].SelectedImageIndex = (online ? 1 : 2);
                }
            }
            catch { }
        }

        void m_SoftRestartTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                DateTime t = DateTime.Now;
                if (t.Hour == int.Parse(G.SystemParam.DailyCloseHour) && (t.Minute == int.Parse(G.SystemParam.DailyCloseMin)))
                {
                    
                    this.Close();
                }

                if((t.Hour==12)&&(t.Minute==1))
                {
                    this.Close();
                }
            }
            catch { }
        }

        /// <summary>
        /// 加载路口和摄像机
        /// </summary>
        public void UpDateTree()
        {
            try
            {
                treeView1.Nodes.Clear();

                if (G.Roads != null)
                {
                    IDictionaryEnumerator ide = G.Roads.GetEnumerator();
                    ide.Reset();
                    while (ide.MoveNext())
                    {
                        Road road = (Road)ide.Value;
                        TreeNode roadnode = new TreeNode();
                        roadnode.Text = road.param.roadname;
                        roadnode.Tag = road.param.roadid;
                        roadnode.Name = "road_" + road.param.roadid;
                        roadnode.ImageIndex = 0;
                        roadnode.SelectedImageIndex = 0;
                        treeView1.Nodes.Add(roadnode);
                    }
                }


                if (G.Views != null)
                {
                    IDictionaryEnumerator idd = G.Views.GetEnumerator();
                    idd.Reset();
                    while (idd.MoveNext())
                    {
                        DeviceView view = (DeviceView)idd.Value;
                        TreeNode[] roadnode = this.treeView1.Nodes.Find("road_" + view.roadparam.roadid, true);
                        if ((roadnode != null) && (roadnode.Length == 1))
                        {
                            TreeNode camnode = new TreeNode();
                            camnode.Text = view.deviceparam.ip + "---" + view.deviceparam.direction.ToString() + "---" + view.deviceparam.type.ToString();
                            camnode.Tag = view.deviceparam.ip;
                            camnode.Name = "device_" + view.deviceparam.ip;
                            camnode.SelectedImageIndex = 1;
                            camnode.ImageIndex = 1;
                            roadnode[0].Nodes.Add(camnode);
                        }
                    }
                }
                treeView1.ExpandAll();
            }
            catch { }
        }

        private void ToolStripMenuItem_shuoming_Click(object sender, EventArgs e)
        {
            try
            {
                Form_Version form_virsion = new Form_Version();
                form_virsion.Owner = this;
                form_virsion.ShowDialog();
                form_virsion.Dispose();
            }
            catch { }
        }

        private void ToolStripMenuItem_baseparam_Click(object sender, EventArgs e)
        {
            try
            {
                param form_param = new param();
                form_param.Owner = this;
                form_param.ShowDialog();
                form_param.Dispose();
            }
            catch { }
        }

        private void Form_Main_FormClosed(object sender, FormClosedEventArgs e)
        {
            System.Threading.Thread stopthread = new System.Threading.Thread(new System.Threading.ThreadStart(MyClose));
            stopthread.Start();
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            e.Node.SelectedImageIndex = e.Node.ImageIndex;
        }

        private void checkBox_debug_CheckedChanged(object sender, EventArgs e)
        {
            if (m_start == false) return;
            try
            {
                if ((G.SystemParam.Save(Enum_SystemParamName.DebugLogEnable, checkBox_debug.Checked) == true))
                {
                    LogTool.gDebugEnable = checkBox_debug.Checked;
                    G.SystemParam.DebugLogEnable = checkBox_debug.Checked;
                    if (checkBox_debug.Checked == true)
                    {
                        LogTool.log.Info("打开调试日志开关");
                    }
                    else
                    {
                        LogTool.log.Info("关闭调试日志开关");
                    }
                }
            }
            catch { }



            //Worker_Bag bag = new Worker_Bag();
            //bag.view = (DeviceView)G.Views["172.16.23.164"];
            //bag.record = new JRCore.protocol.DataRecvRecord();
            //bag.record.P1 = "2.03";
            //bag.record.P2 = "12345";
            //bag.record.P3 = "3";
            //bag.record.P4 = "0";
            //bag.record.P5 = "4";
            //bag.record.P6 = "JARI";
            //bag.record.P7 = "1";
            //bag.record.P8 = "123456789";
            //bag.record.P9 = "Auto";
            //bag.record.P10 = "";
            //bag.record.P11 = "600230001";
            //bag.record.P12 = "320705000000";
            //bag.record.P13 = "320705";
            //bag.record.P14 = "12";
            //bag.record.P15 = "测试路口";
            //bag.record.P16 = "1";
            //bag.record.P17 = "1";
            //bag.record.P18 = "20140520121314555";
            //bag.record.P19 = "2014-05-20 12:13:14";
            //bag.record.P20 = "0";
            //bag.record.P21 = "02";
            //bag.record.P22 = "蓝";
            //bag.record.P23 = "苏G12345";
            //bag.record.P24 = "0";
            //bag.record.P25 = "100";
            //bag.record.P26 = "70";
            //bag.record.P27 = "60";
            //bag.record.P28 = "0";
            //bag.record.P29 = "127.0.0.1";
            //bag.record.P30 = "F:\\KK\\测试路口\\2015\\05\\20\\pic1.jpg";
            //bag.record.P31 = "F:\\KK\\测试路口\\2015\\05\\20\\pic2.jpg";
            //bag.record.P32 = "F:\\KK\\测试路口\\2015\\05\\20\\pic3.jpg";
            //bag.record.P33 = "";
            //bag.record.P34 = "F:\\KK\\测试路口\\2015\\05\\20\\pic4.jpg";
            //bag.record.P35 = "";
            //bag.record.P36 = "";
            //bag.record.P37 = "http://127.0.0.1/KK/测试路口/2015/05/20/pic1.jpg";
            //bag.record.P38 = "http://127.0.0.1/KK/测试路口/2015/05/20/pic1.jpg";
            //bag.record.P39 = "http://127.0.0.1/KK/测试路口/2015/05/20/pic1.jpg";
            //bag.record.P40 = "";
            //bag.record.P41 = "http://127.0.0.1/KK/测试路口/2015/05/20/pic1.jpg";
            //bag.record.P42 = "";
            //bag.record.P43 = "";
            //bag.record.P44 = "";
            //bag.record.P45 = "";
            //bag.record.P46 = "";
            //bag.record.P47 = "";
            //bag.record.P48 = "";
            //bag.record.P49 = "";
            //bag.record.P50 = "";
            //bag.record.P51 = "";
            //bag.record.P52 = "";
            //bag.record.P53 = "";
            //bag.record.Pic1 = File.ReadAllBytes("D:\\123\\1.jpg");
            //bag.record.Pic2 = File.ReadAllBytes("D:\\123\\2.jpg");
            //bag.record.Pic3 = File.ReadAllBytes("D:\\123\\3.jpg");
            //bag.record.Pic4 = null;
            //bag.record.Pic5 = null;
            //bag.record.Pic6 = null;
            //bag.record.Pic7 = null;
            //G.Worker.AddJob(bag);
        }

        private void checkBox_work_CheckedChanged(object sender, EventArgs e)
        {
            if (m_start == false) return;
            try
            {
                if ((G.SystemParam.Save(Enum_SystemParamName.WorkLogEnable, checkBox_work.Checked) == true))
                {
                    LogTool.gWorkEnable = checkBox_work.Checked;
                    G.SystemParam.WorkLogEnable = checkBox_work.Checked;
                    if (checkBox_work.Checked == true)
                    {
                        LogTool.log.Info("打开业务日志开关");
                    }
                    else
                    {
                        LogTool.log.Info("关闭业务日志开关");
                    }
                }
            }
            catch { }
        }

        private void Form_Main_Shown(object sender, EventArgs e)
        {
            m_start = true;
        }

        private void toolStripMenuItem_brt_Click(object sender, EventArgs e)
        {
            try
            {
                Form_brt form = new Form_brt();
                form.Owner = this;
                form.ShowDialog();
                form.Dispose();
            }
            catch { }
        }

        private void toolStripMenuItem_road_Click(object sender, EventArgs e)
        {
            try
            {
                road form_road = new road();
                form_road.Owner = this;
                form_road.ShowDialog();
                form_road.Dispose();
            }
            catch { }
        }

        private void toolStripMenuItem_device_Click(object sender, EventArgs e)
        {
            try
            {
                camera form_camera = new camera();
                form_camera.Owner = this;
                form_camera.ShowDialog();
                form_camera.Dispose();
            }
            catch { }
        }

        private void toolStripMenuItem_tingji_Click(object sender, EventArgs e)
        {
            try
            {
                Form_Tongji form_tongji = new Form_Tongji();
                form_tongji.Owner = this;
                form_tongji.ShowDialog();
                form_tongji.Dispose();
            }
            catch { }
        }

    }
}
